package com.googlecode.flealancemarket.service.facades.impl;

import com.googlecode.flealancemarket.metamodel.Category;
import com.googlecode.flealancemarket.metamodel.Employer;
import com.googlecode.flealancemarket.metamodel.Freelancer;
import com.googlecode.flealancemarket.metamodel.Job;
import com.googlecode.flealancemarket.metamodel.JobMessage;
import com.googlecode.flealancemarket.metamodel.User;
import com.googlecode.flealancemarket.service.facades.JobFacade;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.transaction.annotation.Transactional;

public class JobFacadeImpl extends HibernateDaoSupport implements JobFacade{

    @Transactional
    public Job saveJob(Job j, long authorId, long categoryId) {
        Session s = getSessionFactory().getCurrentSession();
        Employer author = (Employer) s
                                .createCriteria(Employer.class)
                                .add(Restrictions.eq("_id", authorId))
                                .uniqueResult();
        if(author == null)
            return null;
        j.setAuthor(author);

        Category category = (Category) s
            .createCriteria(Category.class)
            .add(Restrictions.eq("_id", categoryId))
            .uniqueResult();
        
            if(category == null)
                return null;

        j.setCategory(category);
        long id = (Long) s.save(j);
        j.set_id(id);
        return j;
    }

    @Transactional
    public Job getJobWithMessages(long id) {
        Session sess = getSessionFactory().getCurrentSession();
        Job job = (Job)sess
                        .createCriteria(Job.class)
                        .add(Restrictions.eq("_id", id))
                        .uniqueResult();
        if(job==null)
            return null;

        List<JobMessage> list = sess
                                    .createCriteria(JobMessage.class)
                                    .add(Restrictions.eq("job._id", id))
                                    .list();

        job.setJobMessages(list);

        return job;
    }

    @Transactional
    public JobMessage saveJobMessage(JobMessage jobMessage, long freelancerId) {
        Session session = getSessionFactory().getCurrentSession();
        Freelancer f = (Freelancer) session
                        .createCriteria(Freelancer.class)
                        .add(Restrictions.eq("_id", freelancerId))
                        .uniqueResult();
        if(f==null)
            return null;
        jobMessage.setAuthor(f);
        long id = (Long)session.save(jobMessage);
        jobMessage.set_id(id);
        return jobMessage;
    }

    @Transactional
    public List<Job> getJobsForUser(User user) {
        if(user instanceof Freelancer)
            return generateFreelancerCriteria(user);
        return generateEmployerCriteria(user);
    }

    private List<Job> generateFreelancerCriteria(User user){
        Freelancer fl = (Freelancer)user;
        Criteria crit =
                getSessionFactory().getCurrentSession()
                .createCriteria(Job.class)
                .createAlias("jobMessages", "msg")
                .setFetchMode("jobMessages", FetchMode.JOIN)
                .setFetchMode("msg.author", FetchMode.JOIN)
                .add(Restrictions.eq("msg.author", fl));
        return (List<Job>)crit.list();
    }
    private List<Job> generateEmployerCriteria(User user){
        Employer emp = (Employer)user;
        Criteria crit =
                getSessionFactory().getCurrentSession()
                .createCriteria(Job.class)
                .add(Restrictions.eq("author", emp));
        return crit.list();
    }
}